package ls.controller;

import java.util.Collection;
import ls.model.Moaning;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import ls.model.Reply;
import ls.model.Vote;

@Controller()
@RequestMapping("/moanings")
public class MoaningController extends BaseController {
    protected static final String JSP_NEW_MOANING = "newMoaning";
    protected static final String JSP_MOANING = "moaning";

    protected static final String ATTR_JUST_ENTERED = "justEntered";
    protected static final String ATTR_VOTES = "votes";
    protected static final String ATTR_BEST_REPLY = "bestReply";
    
    protected static final int MINIMUM_VOTES = 3;

    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView defaultPage() {
        ModelAndView view = new ModelAndView(JSP_NEW_MOANING);
        Moaning defaultMoaning = new Moaning();
        putMoaning(view, defaultMoaning);
        return view;
    }

    @RequestMapping(method = RequestMethod.POST)
    public ModelAndView addMoaning(Moaning moaning) {
        getMoaningRepository().saveMoaning(moaning);
        ModelAndView view = new ModelAndView(JSP_NEW_MOANING);
        view.addObject(ATTR_JUST_ENTERED, moaning);
        return view;
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public ModelAndView permalink(@PathVariable("id") long id) {
        ModelAndView view = new ModelAndView(JSP_MOANING);
        Moaning moaning = getMoaningRepository().getMoaning(id);
        putMoaning(view, moaning);
        if (moaning.getVotes().size() >= MINIMUM_VOTES) {
            view.addObject(ATTR_BEST_REPLY, 
                   calculateBestReply(moaning.getVotes()));  
        }
        return view;
    }

    protected Reply calculateBestReply(Collection<Vote> votes) {
        Map<Reply, Long> reply2score = new HashMap<Reply, Long>();
        for (Vote vote: votes) {
            Reply firstChoice = vote.getChoices().get(0).getReply();
            if (reply2score.containsKey(firstChoice)) {
                reply2score.put(firstChoice, reply2score.get(firstChoice) + 1);
            }
            else {
                reply2score.put(firstChoice, 1L);
            }
        }
        SortedMap<Long, Reply> score2reply = new TreeMap<Long, Reply>();
        for (Reply reply: reply2score.keySet()) {
            score2reply.put(reply2score.get(reply), reply);
        }
        return score2reply.get(score2reply.lastKey());
    }
}
